package com.lhb.aicodemother.ai;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.lhb.aicodemother.ai.model.enums.CodeGenTypeEnum;
import com.lhb.aicodemother.ai.tools.FileWriteTool;
import com.lhb.aicodemother.exception.BusinessException;
import com.lhb.aicodemother.exception.ErrorCode;
import com.lhb.aicodemother.service.ChatHistoryService;
import dev.langchain4j.community.store.memory.chat.redis.RedisChatMemoryStore;
import dev.langchain4j.data.message.ToolExecutionResultMessage;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.service.AiServices;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

@Configuration
@Slf4j
public class AiCodeGeneratorServiceFactory {
    @Resource
    private ChatModel chatModel;

    @Resource
    private StreamingChatModel openAiStreamingChatModel;

    @Resource
    private RedisChatMemoryStore redisChatMemoryStore;

    @Resource
    private StreamingChatModel reasoningStreamingChatModel;

    @Resource
    private ChatHistoryService chatHistoryService;

    /*
    * Ai服务实力缓存
    * */
    private final Cache<String,AiCodeGeneratorService> serviceCache = Caffeine.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(Duration.ofMinutes(30))
            .expireAfterAccess(Duration.ofMinutes(10))
            .removalListener((key, value, cause) -> {
                log.debug("AI服务实力被移除，appId:{},原因:{}",key,cause);
            })
            .build();

    /*
    * 根据appId获取服务
    * */
    public AiCodeGeneratorService getAICodeGeneratorService(long appId) {
        return getAICodeGeneratorService(appId,CodeGenTypeEnum.HTML);
    }

    /*
    * 根据appId和代码生成类型获取服务
    * */
    public AiCodeGeneratorService getAICodeGeneratorService(long appId,CodeGenTypeEnum codeGenTypeEnum) {
        String cacheKey = buildCacheKey(appId, codeGenTypeEnum);
        return serviceCache.get(cacheKey,key -> createAiCodeGeneratorService(appId,codeGenTypeEnum));
    }

    /*
    * 构建缓存键
    * */
    private String buildCacheKey(long appId,CodeGenTypeEnum codeGenTypeEnum) {
        return appId + "_" + codeGenTypeEnum.getValue();
    }



    /*
    * 创建新的AI服务实力 (为了隔离对话记忆，将每个appId对应一个对话记忆对应一个AIService)
    * */
    private AiCodeGeneratorService createAiCodeGeneratorService(long appId, CodeGenTypeEnum codeGenTypeEnum) {
        // 根据appId构建独立的对话记忆
        MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
                .id(appId)
                .chatMemoryStore(redisChatMemoryStore)
                .maxMessages(50)
                .build();

        // 从数据库加载历史对话到记忆中
        chatHistoryService.loadChatHistoryToMemory(appId,chatMemory,20);

        // 根据代码生成类型选择不同的模型配置
        return switch (codeGenTypeEnum){
            case VUE_PROJECT -> AiServices.builder(AiCodeGeneratorService.class)
                    .streamingChatModel(reasoningStreamingChatModel)
                    .chatMemoryProvider(memoryId -> chatMemory)
                    .tools(new FileWriteTool())
                    .hallucinatedToolNameStrategy(toolExecutionRequest -> ToolExecutionResultMessage.from(
                            toolExecutionRequest,"Error: there is no tool called" + toolExecutionRequest.name()
                    ))
                    .build();

            case HTML,MULTI_FILE -> AiServices.builder(AiCodeGeneratorService.class)
                    .streamingChatModel(openAiStreamingChatModel)
                    .chatModel(chatModel)
                    .chatMemory(chatMemory)
                    .build();
            default -> throw new BusinessException(ErrorCode.SYSTEM_ERROR,"不支持的代码生成类型：" + codeGenTypeEnum.getValue());
        };
    }

    /*
    * 初始化AI服务
    * */
//    @Bean
//    public AiCodeGeneratorService aiCodeGeneratorService() {
//        return AiServices.builder(AiCodeGeneratorService.class)
//                .chatModel(chatModel)
//                .streamingChatModel(openAiStreamingChatModel)
//                .chatMemoryProvider(appId -> {
//                    MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
//                            .id(appId)
//                            .chatMemoryStore(redisChatMemoryStore)
//                            .maxMessages(20)
//                            .build();
//
//                    // 清除缓存，防止重复加载
//                    chatMemory.clear();
//                    // 加载历史对话
//                    chatHistoryService.loadChatHistoryToMemory((Long) appId, chatMemory, 20);
//                    return chatMemory;
//                })
//                .build();
//    }
}
